/*
 * Copyright 2016 Elvis Hew
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.elvishew.xlogsample.slice;

import com.elvishew.xlogsample.Constants;
import com.elvishew.xlogsample.ResourceTable;
import com.elvishew.xlog.LogLevel;
import com.elvishew.xlog.Logger;
import com.elvishew.xlog.XLog;
import com.elvishew.xlog.printer.OhosPrinter;
import com.elvishew.xlog.printer.Printer;
import com.elvishew.xlogsample.RecyclerViewPrinter;
import com.elvishew.xlogsample.XLogSampleApplication;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.agp.window.dialog.CommonDialog;
import ohos.agp.window.dialog.PopupDialog;
import ohos.app.Context;
import ohos.event.commonevent.*;
import ohos.hiviewdfx.HiLog;

import static ohos.bundle.IBundleManager.PERMISSION_GRANTED;


public class MainAbilitySlice extends AbilitySlice {


    private static final String MESSAGE = "Simple message";

    private static final int[] LEVELS = new int[]{LogLevel.VERBOSE, LogLevel.DEBUG, LogLevel.INFO,
            LogLevel.WARN, LogLevel.ERROR};
    private static final String[] LEVEL_STRING = new String[]{"VERBOSE", "DEBUG", "INFO", "WARN", "ERROR"};
    private static final String[] STACK_TRACE_DEPTHS = new String[]{"0", "1", "2", "3", "4", "5"};


    private static final int PERMISSIONS_REQUEST_EXTERNAL_STORAGE = 1;
    private Text tagContentTv;
    private Text levelContentTv;
    private ToggleButton threadTb;
    private ToggleButton borderTb;
    private ToggleButton traceInfoTb;
    private ListContainer listContainer;
    private Printer viewPrinter;
    private Button printBt;
    private Text traceDepthContentTv;
    private int levelPosition;
    private int traceDepthPosition;


    private boolean hasPermission;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        ComponentContainer rootLayout = (ComponentContainer) LayoutScatter.getInstance(this)
                .parse(com.elvishew.xlogsample.ResourceTable.Layout_ability_main, null, false);
        HiLog.info(Constants.LABEL_LOG, "onStart");
        HiLog.debug(Constants.LABEL_LOG, "test debug");
        tagContentTv = (Text) rootLayout.findComponentById(com.elvishew.xlogsample.ResourceTable.Id_tag_content_tv);
        tagContentTv.setClickedListener(component -> {
            createDialog();
        });

        levelContentTv = (Text) rootLayout.findComponentById(com.elvishew.xlogsample.ResourceTable.Id_level_content_tv);
        levelContentTv.setClickedListener(component -> {
            createPopDialog();
        });
        threadTb = (ToggleButton) rootLayout.findComponentById(com.elvishew.xlogsample.ResourceTable.Id_thread_tb);

        borderTb = (ToggleButton) rootLayout.findComponentById(com.elvishew.xlogsample.ResourceTable.Id_border_tb);

        traceInfoTb = (ToggleButton) rootLayout.findComponentById(com.elvishew.xlogsample.ResourceTable.Id_trace_info_tb);
        traceInfoTb.setCheckedStateChangedListener((absButton, b) -> {
            if (b) {
                traceDepthContentTv.setEnabled(true);
            } else {
                traceDepthContentTv.setEnabled(false);
            }
        });
        traceDepthContentTv = (Text) rootLayout.findComponentById(com.elvishew.xlogsample.ResourceTable.Id_trace_depth_content_tv);
        traceDepthContentTv.setEnabled(false);
        traceDepthContentTv.setClickedListener(component -> {
            createTraceDepthPopDialog();
        });

        listContainer = (ListContainer) rootLayout.findComponentById(com.elvishew.xlogsample.ResourceTable.Id_listView);
        printBt = (Button) rootLayout.findComponentById(com.elvishew.xlogsample.ResourceTable.Id_print);
        printBt.setClickedListener(component -> {
            printLog();
        });

        viewPrinter = new RecyclerViewPrinter(this, listContainer);

        XLog.printers(viewPrinter).i("XLog is ready.\nPrint your log now!");
        setUIContent(rootLayout);


        // Check permission.
        getPermission();

        subscriberCommon();
    }

    /**
     * 接受权限回调结果
     */
    private void subscriberCommon() {
        HiLog.info(Constants.LABEL_LOG, "slice subscriber");
        try {
            String event = Constants.COMMON_EVENT_ACTION;
            MatchingSkills matchingSkills = new MatchingSkills();
            matchingSkills.addEvent(event); // 自定义事件
            CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
            CommonEventSubscriber commonEventSubscriber = new CommonEventSubscriber(subscribeInfo) {
                @Override
                public void onReceiveEvent(CommonEventData commonEventData) {
                    HiLog.info(Constants.LABEL_LOG, "slice onReceiveEvent");
                    if (commonEventData.getData() == null) {
                        HiLog.info(Constants.LABEL_LOG, "no data");
                        return;
                    }

                    if (Constants.GRANT_PERMISSION.equals(commonEventData.getData())) {
                        hasPermission = true;
                    } else {
                        hasPermission = false;
                    }
                }
            };
            CommonEventManager.subscribeCommonEvent(commonEventSubscriber);
        } catch (Exception e) {
            HiLog.error(Constants.LABEL_LOG,e.toString());
        }
    }

    /**
     * get permission_WRITE_USER_STORAGE
     */
    private void getPermission() {
        if (verifySelfPermission("ohos.permission.WRITE_USER_STORAGE") != PERMISSION_GRANTED) {
            HiLog.info(Constants.LABEL_LOG, "no Permission");
            // 应用未被授予权限
            if (canRequestPermission("ohos.permission.WRITE_USER_STORAGE")) {
                // 是否可以申请弹框授权(首次申请或者用户未选择禁止且不再提示)
                requestPermissionsFromUser(
                        new String[]{"ohos.permission.WRITE_USER_STORAGE"}, Constants.PERMISSION_CODE);
            }
        } else {
            hasPermission = true;
            HiLog.info(Constants.LABEL_LOG, "has Permission");
        }
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    PopupDialog popupDialog;
    private void createPopDialog() {
        popupDialog = new PopupDialog(this, levelContentTv, 300, 500);
        ListContainer listContainer = new ListContainer(MainAbilitySlice.this);
        listContainer.setItemProvider(new PopupAdapter(MainAbilitySlice.this, LEVEL_STRING));
        listContainer.setItemClickedListener((listContainer1, component, i, l) -> {
            levelPosition = i;
            levelContentTv.setText(LEVEL_STRING[i]);
            popupDialog.destroy();
        });
        popupDialog.setCustomComponent(listContainer);
        popupDialog.show();
    }


    private void createTraceDepthPopDialog() {
        popupDialog = new PopupDialog(this, traceDepthContentTv, 300, 500);
        ListContainer listContainer = new ListContainer(MainAbilitySlice.this);
        listContainer.setItemProvider(new PopupAdapter(MainAbilitySlice.this, STACK_TRACE_DEPTHS));
        listContainer.setItemClickedListener((listContainer1, component, i, l) -> {
            traceDepthPosition = i;
            traceDepthContentTv.setText(i + "");
            popupDialog.destroy();
        });
        popupDialog.setCustomComponent(listContainer);
        popupDialog.show();
    }

    private void createDialog() {
        HiLog.info(Constants.LABEL_LOG, "createDialog");
        ComponentContainer customLayout = (ComponentContainer) LayoutScatter.getInstance(this)
                .parse(com.elvishew.xlogsample.ResourceTable.Layout_dialog_change_tag, null, false);
        TextField textField = (TextField) customLayout.findComponentById(com.elvishew.xlogsample.ResourceTable.Id_custom_tag);
        CommonDialog commonDialog = new CommonDialog(MainAbilitySlice.this);
        commonDialog.setTitleText("Change tag");
        commonDialog.setContentCustomComponent(customLayout);
        commonDialog.setButton(0, "取消", (iDialog, i) -> {
            commonDialog.destroy();
        });
        commonDialog.setButton(2, "确定", (iDialog, i) -> {
            String tag = textField.getText().trim();
            if (!tag.isEmpty()) {
                tagContentTv.setText(tag);
            }
            commonDialog.destroy();
        });
        commonDialog.show();
    }


    class PopupAdapter extends BaseItemProvider {
        String[] strings;
        Context context;

        public PopupAdapter(Context context, String[] strings) {
            this.context = context;
            this.strings = strings;
        }


        @Override
        public int getCount() {
            return strings.length;
        }

        @Override
        public Object getItem(int i) {
            return null;
        }

        @Override
        public long getItemId(int i) {
            return 0;
        }

        @Override
        public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
            LayoutScatter layoutScatter = LayoutScatter.getInstance(context);
            ComponentContainer rootLayout = (ComponentContainer) layoutScatter.parse(com.elvishew.xlogsample.ResourceTable.Layout_item_popup_window, null, false);
            Text text = (Text) rootLayout.findComponentById(ResourceTable.Id_popup_tv);
            text.setText(strings[i]);
            return text;
        }
    }


    /**
     * Print the configured log.
     */
    private void printLog() {
        Logger.Builder builder = new Logger.Builder();

        String tag = tagContentTv.getText();
        if (!tag.isEmpty()) {
            builder.tag(tag);
        }

        if (threadTb.isChecked()) {
            builder.t();
        } else {
            builder.nt();
        }

        if (traceInfoTb.isChecked()) {
            builder.st(Integer.parseInt(STACK_TRACE_DEPTHS[traceDepthPosition]));
        } else {
            builder.nst();
        }

        if (borderTb.isChecked()) {
            builder.b();
        } else {
            builder.nb();
        }

        // Print the log to view, logcat and file.
        HiLog.info(Constants.LABEL_LOG, "print HASPERMISSON:" + hasPermission);
        if (hasPermission) {
            builder.printers(
                    viewPrinter,
                    new OhosPrinter(),
                    XLogSampleApplication.globalFilePrinter);
        } else {
            builder.printers(
                    viewPrinter,
                    new OhosPrinter());
        }

        Logger logger = builder.build();

        int level = LEVELS[levelPosition];
        switch (level) {
            case LogLevel.VERBOSE:
                logger.v(MESSAGE);
                break;
            case LogLevel.DEBUG:
                logger.d(MESSAGE);
                break;
            case LogLevel.INFO:
                logger.i(MESSAGE);
                break;
            case LogLevel.WARN:
                logger.w(MESSAGE);
                break;
            case LogLevel.ERROR:
                logger.e(MESSAGE);
                break;
        }
    }


}
